package com.whosly.mysql.protocol.packet.impl;

import com.whosly.mysql.protocol.jdbc.MySQLMessage;
import com.whosly.mysql.protocol.packet.jdbc.MySQLPacket;
import com.whosly.mysql.protocol.packet.util.NettyBufferUtil;
import io.netty.buffer.ByteBuf;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author fengyang
 * @date 2023/7/20 上午10:33
 * @see <a href="yueny09@163.com">mailTo: yueny09@163.com</a>
 */
public class AuthSwitchRequestPacket extends MySQLPacket
        implements Serializable
{

    private static byte STATUS = (byte) 0xfe;
    private String authMethodName;
    private byte[] authMethodData;

    @Override
    public void read(byte[] bodyBytes)
    {
        MySQLMessage mm = new MySQLMessage(bodyBytes);

        mm.read();
        authMethodName = mm.readStringWithLength();
        authMethodData = mm.readBytes();
    }

    @Override
    public ByteBuf writeBuf(ByteBuf buffer)
    {
        NettyBufferUtil.writeUB3(buffer, calcPacketSize());
        buffer.writeByte(getPackId());

        buffer.writeByte(STATUS);
        NettyBufferUtil.writeWithLength(buffer, authMethodName);
        NettyBufferUtil.writeWithLength(buffer, authMethodData);
        buffer.writeByte((byte) 0x00);

        return buffer;
    }

    @Override
    public int calcPacketSize() {
        int packetLength = 0;

        packetLength += 1; // status
        packetLength += authMethodName.length() * 2;
        packetLength += 1; // the terminated NULL for authMethodName
        packetLength += authMethodData.length;
        packetLength += 1;

        return packetLength;
    }

    public static byte getSTATUS() {
        return STATUS;
    }

    public static void setSTATUS(final byte STATUS) {
        AuthSwitchRequestPacket.STATUS = STATUS;
    }

    public String getAuthMethodName() {
        return authMethodName;
    }

    public void setAuthMethodName(final String authMethodName) {
        this.authMethodName = authMethodName;
    }

    public byte[] getAuthMethodData() {
        return authMethodData;
    }

    public void setAuthMethodData(final byte[] authMethodData) {
        this.authMethodData = authMethodData;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final AuthSwitchRequestPacket that = (AuthSwitchRequestPacket) o;
        return Objects.equals(authMethodName, that.authMethodName) && Arrays.equals(authMethodData, that.authMethodData);
    }

    @Override
    public int hashCode() {

        int result = Objects.hash(authMethodName);
        result = 31 * result + Arrays.hashCode(authMethodData);
        return result;
    }
}
